Merge pull request #1645 from dsander/retry-twitter-action-agent

Allow TwitterUserAgent to retry failed actions

Dominik Sander 8 年之前
父節點
當前提交
f42ad96ed6

+ 10 - 1
app/models/agents/twitter_action_agent.rb

@@ -16,6 +16,7 @@ module Agents
16 16
       Set `expected_receive_period_in_days` to the maximum amount of time that you'd expect to pass between Events being received by this Agent.
17 17
       Set `retweet` to either true or false.
18 18
       Set `favorite` to either true or false.
19
+      Set `emit_error_events` to true to emit an Event when the action failed, otherwise the action will be retried.
19 20
     MD
20 21
 
21 22
     def validate_options
@@ -25,6 +26,9 @@ module Agents
25 26
       unless retweet? || favorite?
26 27
         errors.add(:base, "at least one action must be true")
27 28
       end
29
+      if emit_error_events?.nil?
30
+        errors.add(:base, "emit_error_events must be set to 'true' or 'false'")
31
+      end
28 32
     end
29 33
 
30 34
     def working?
@@ -36,6 +40,7 @@ module Agents
36 40
         'expected_receive_period_in_days' => '2',
37 41
         'favorite' => 'false',
38 42
         'retweet' => 'true',
43
+        'emit_error_events' => 'false'
39 44
       }
40 45
     end
41 46
 
@@ -47,6 +52,10 @@ module Agents
47 52
       boolify(options['favorite'])
48 53
     end
49 54
 
55
+    def emit_error_events?
56
+      boolify(options['emit_error_events'])
57
+    end
58
+
50 59
     def receive(incoming_events)
51 60
       tweets = tweets_from_events(incoming_events)
52 61
 
@@ -54,6 +63,7 @@ module Agents
54 63
         twitter.favorite(tweets) if favorite?
55 64
         twitter.retweet(tweets) if retweet?
56 65
       rescue Twitter::Error => e
66
+        raise e unless emit_error_events?
57 67
         create_event :payload => {
58 68
           'success' => false,
59 69
           'error' => e.message,
@@ -71,4 +81,3 @@ module Agents
71 81
     end
72 82
   end
73 83
 end
74
-

+ 15 - 0
db/migrate/20160823151303_set_emit_error_event_for_twitter_action_agents.rb

@@ -0,0 +1,15 @@
1
+class SetEmitErrorEventForTwitterActionAgents < ActiveRecord::Migration
2
+  def up
3
+    Agents::TwitterActionAgent.find_each do |agent|
4
+      agent.options['emit_error_events'] = 'true'
5
+      agent.save!(validate: false)
6
+    end
7
+  end
8
+
9
+  def down
10
+    Agents::TwitterActionAgent.find_each do |agent|
11
+      agent.options.delete('emit_error_events')
12
+      agent.save!(validate: false)
13
+    end
14
+  end
15
+end

+ 43 - 12
spec/models/agents/twitter_action_agent_spec.rb

@@ -24,11 +24,11 @@ describe Agents::TwitterActionAgent do
24 24
 
25 25
     context 'when set up to retweet' do
26 26
       before do
27
-        @agent = build_agent({
28
-          'expected_receive_period_in_days' => '2',
27
+        @agent = build_agent(
29 28
           'favorite' => 'false',
30 29
           'retweet' => 'true',
31
-        })
30
+          'emit_error_events' => 'true'
31
+        )
32 32
         @agent.save!
33 33
       end
34 34
 
@@ -68,9 +68,9 @@ describe Agents::TwitterActionAgent do
68 68
     context 'when set up to favorite' do
69 69
       before do
70 70
         @agent = build_agent(
71
-          'expected_receive_period_in_days' => '2',
72 71
           'favorite' => 'true',
73 72
           'retweet' => 'false',
73
+          'emit_error_events' => 'true'
74 74
         )
75 75
         @agent.save!
76 76
       end
@@ -107,13 +107,48 @@ describe Agents::TwitterActionAgent do
107 107
         end
108 108
       end
109 109
     end
110
+
111
+    context 'with emit_error_events set to false' do
112
+      it 'does re-raises the exception on failure' do
113
+        agent = build_agent
114
+
115
+        stub(agent.twitter).retweet(anything) {
116
+          raise Twitter::Error.new('uh oh')
117
+        }
118
+
119
+       expect { agent.receive([@event1]) }.to raise_error(StandardError, /uh oh/)
120
+
121
+      end
122
+    end
110 123
   end
111 124
 
112 125
   describe "#validate_options" do
126
+    it 'the default options are valid' do
127
+      agent = build_agent(described_class.new.default_options)
128
+
129
+      expect(agent).to be_valid
130
+    end
131
+
132
+    context 'emit_error_events' do
133
+      it 'can be set to true' do
134
+        agent = build_agent(described_class.new.default_options.merge('emit_error_events' => 'true'))
135
+        expect(agent).to be_valid
136
+      end
137
+
138
+      it 'must be a boolean' do
139
+        agent = build_agent(described_class.new.default_options.merge('emit_error_events' => 'notbolean'))
140
+        expect(agent).not_to be_valid
141
+      end
142
+    end
143
+
144
+    it 'expected_receive_period_in_days must be set' do
145
+      agent = build_agent(described_class.new.default_options.merge('expected_receive_period_in_days' => ''))
146
+      expect(agent).not_to be_valid
147
+    end
148
+
113 149
     context 'when set up to neither favorite or retweet' do
114 150
       it 'is invalid' do
115 151
         agent = build_agent(
116
-          'expected_receive_period_in_days' => '2',
117 152
           'favorite' => 'false',
118 153
           'retweet' => 'false',
119 154
         )
@@ -129,11 +164,7 @@ describe Agents::TwitterActionAgent do
129 164
     end
130 165
 
131 166
     it 'checks if events have been received within the expected time period' do
132
-      agent = build_agent(
133
-        'expected_receive_period_in_days' => '2',
134
-        'favorite' => 'false',
135
-        'retweet' => 'true',
136
-      )
167
+      agent = build_agent
137 168
       agent.save!
138 169
 
139 170
       expect(agent).not_to be_working # No events received
@@ -147,10 +178,10 @@ describe Agents::TwitterActionAgent do
147 178
     end
148 179
   end
149 180
 
150
-  def build_agent(options)
181
+  def build_agent(options = {})
151 182
     described_class.new do |agent|
152 183
       agent.name = 'twitter stuff'
153
-      agent.options = options
184
+      agent.options = agent.default_options.merge(options)
154 185
       agent.service = services(:generic)
155 186
       agent.user = users(:bob)
156 187
     end